local cjson     = require "cjson"
local string    = require "string"
local table_new = require "table.new"
local table     = require "table"
local jwt       = require "resty.jwt"
local redis     = require "redis"
local keysutils = require "keysutils"
local utilsdate = require "utilsdate"
local utils     = require "utils"
local global    = require "global"

require "functions"

local _M={}

local function getIp()
    local headers=ngx.req.get_headers()
    local clientIP = headers["x-forwarded-for"]
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
        clientIP = headers["Proxy-Client-IP"]
    end
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
        clientIP = headers["WL-Proxy-Client-IP"]
    end
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
        clientIP = ngx.var.remote_addr
    end
    -- 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
    if clientIP ~= nil and string.len(clientIP) >15  then
        local pos  = string.find(clientIP, ",", 1)
        clientIP = string.sub(clientIP,1,pos-1)
    end
    return clientIP
end

function _M.access()
    local arg=ngx.req.get_uri_args()
    local secret = string.format("%s-%s", global.get_appname(), global.get_appversion())
    local jwtval = arg.jwt
    if jwtval then
        local jwtobj = jwt:verify(secret, jwtval)
        if not jwtobj or not jwtobj.payload or not jwtobj.payload.token or not jwtobj.payload.id then
            ngx.say(cjson.encode({errcode=401,errmsg='参数解析错误[43]'}))
            ngx.exit(401)
            return
        end
        
        local rediscli = redis:new(global.get_redis_conf())
        if not DEBUG then
            local key = keysutils.get_user_token(jwtobj.payload.id)
            local oldtoken = rediscli:get(key)
            if oldtoken~=jwtobj.payload.token then
                ngx.say(cjson.encode({errcode=400,errmsg='安全检测中...',oldtoken=oldtoken,curtoken=jwtobj.payload.token}))
                ngx.exit(401)
                return
            end
        end

        local args = ngx.req.get_uri_args()
        args.id = jwtobj.payload.id
        ngx.req.set_uri_args(args)
    else
        local ip = getIp()
        local privateip = utils.isprivateip(ip)
        if not privateip then
            ngx.say(cjson.encode({errcode=401,errmsg='系统繁忙,请稍后再试!'}))
            ngx.exit(401)
            return
        end
    end
end

return _M
